package com.haust.cart.service.impl;

import com.haust.cart.service.CartService;
import com.haust.cart.vo.Cart;
import com.haust.cart.vo.CartItem;
import com.haust.commons.pojo.HaustResult;
import com.haust.dao.RedisDao;
import com.haust.pojo.TbItem;
import com.haust.pojo.TbUser;
import com.codingapi.txlcn.tc.annotation.TccTransaction;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class CartServiceImpl implements CartService {
    @Autowired
    private RedisDao redisDao;

    @Value("${Haust.frontend.cart.keyPrefix}")
    private String cartKeyPrefix;

    @Value("${Haust.frontend.details.item}")
    private String itemKeyPrefix;

    /**
     * 创建订单的步骤之：
     * 删除购物车中添加的商品
     *
     * @param list   map   key      valule
     *               itemId  通过商品id查找 购物车中的商品
     *               num     用于事务回滚时的 数据恢复
     * @param userId 用户的id ，通过用户id,查找购物车
     * @return
     */
    @Override
    @TccTransaction
    public HaustResult clearCart4CreateOrder(List<Map<String, Object>> list, Long userId) {

        Cart cart = redisDao.get(cartKeyPrefix + userId);
        for (Map<String, Object> map : list) {
            //获取商品主键
            String itemId = map.get("itemId").toString();
            //将 该商品移除
            cart.getItems().remove(itemId);
        }
        redisDao.set(cartKeyPrefix + userId, cart);

        return HaustResult.ok();
    }

    public HaustResult confirmClearCart4CreateOrder(List<Map<String, Object>> list, Long userId) {
        return HaustResult.ok();
    }

    public HaustResult cancelClearCart4CreateOrder(List<Map<String, Object>> list, Long userId) {
        //得到购物车
        Cart cart = redisDao.get(cartKeyPrefix + userId);
        //如果出错，恢复数据
        for (Map<String, Object> map : list) {
            //获取商品id
            Long itemId = Long.parseLong(map.get("itemId").toString());
            //获取购物车原始数量
            Integer num = Integer.parseInt(map.get("num").toString());
            //获取商品信息
            TbItem tbItem = redisDao.get(itemKeyPrefix + itemId);
            //设置购物车商品数量
            tbItem.setNum(num);

            CartItem cartItem = new CartItem();
            //转移属性值
            BeanUtils.copyProperties(tbItem, cartItem);
            cart.getItems().put(itemId.toString(), cartItem);
        }
        redisDao.set(cartKeyPrefix+userId,cart);
        return HaustResult.error("已恢复");
    }

    /**
     * 去结算 功能 虽并未是 结算，也需要 判断商品的时候是否足够
     *
     * @param id   购物车中商品的id
     * @param user
     * @return
     */
    @Override
    public HaustResult goSettlement(Long[] id, TbUser user) {
        //1、获取购物车
        Cart cart = redisDao.get(cartKeyPrefix + user.getId());
        //2、创建结果集合
        ArrayList<CartItem> result = new ArrayList<>(id.length);

        Set<String> strings = cart.getItems().keySet();

        for (String itemId : strings) {
            TbItem item = redisDao.get(itemKeyPrefix + itemId);
            CartItem cartItem = cart.getItems().get(itemId);
            cartItem.setEnough(item.getNum() > cartItem.getNum());
            result.add(cartItem);
        }

        return HaustResult.ok(result);
    }

    /**
     * 步骤：
     * 1、先要判断 该商品的数量是否 是否够？
     * 够：可以修改
     * 不够： 然会 error
     * 2、获取购物车对象
     * 3、修改购物车中该物品的数量
     * 修改购物车商品 数量
     *
     * @param itemId 商品id
     * @param num    购物车商品数量
     * @param user   用户
     * @return
     */
    @Override
    public HaustResult updateItemNum(Long itemId, Integer num, TbUser user) {
        //1、获取 商品
        TbItem tbItem = redisDao.get(itemKeyPrefix + itemId);
        //2、判断，要修改的数量是否 超过商品的最大数量
        if (tbItem.getNum() < num) {
            return HaustResult.error("商品数量不足");
        }

        //获取购物车
        Cart cart = redisDao.get(cartKeyPrefix + user.getId());
        CartItem cartItem = cart.getItems().get(itemId.toString());

        //修改 购物车中该商品的数量
        cartItem.setNum(num);

        //修改之后，再写进 redis
        redisDao.set(cartKeyPrefix + user.getId(), cart);
        return HaustResult.ok();
    }

    @Override
    public HaustResult showCart(TbUser user) {
        // 拼接 key
        String key = cartKeyPrefix + user.getId();

        //从Redis中查，看有没有该购物车
        Cart cart = redisDao.get(key);

        if (cart == null) {

            //如果没有，创建新的购物车
            cart = new Cart();
            //放入redis中
            redisDao.set(key, cart);
        }
        //获取购物车数据集合
        Collection<CartItem> values = cart.getItems().values();
        return HaustResult.ok(values);
    }


    /**
     * @param itemId 商品id
     * @param num    商品数量
     * @param user   用户
     * @return
     */
    @Override
    public HaustResult addItem(Long itemId, Integer num, TbUser user) {
        //老师的逻辑写法
        //1、获取redis中的商品
        TbItem tbItem = redisDao.get(itemKeyPrefix + itemId);
        //2、获取购物车
        Cart cart = redisDao.get(cartKeyPrefix + user.getId());

        //3、将 TbItem对象转化为 CartItem对象
        CartItem cartItem = new CartItem();
        BeanUtils.copyProperties(tbItem, cartItem);
        //设置num  tbItem中的num值的是商品的数量，而cartItem中num表示的是添加到购物车中该商品的数量
        cartItem.setNum(num);

        //4、判断购物车是否为null
        if (cart == null) {
            //新建购物车
            cart = new Cart();
            //给购物车中添加商品 一个商品对应一个 map  ,map的key为商品id,map的值为CartItem
            Map<String, CartItem> items = cart.getItems();
            items.put(itemId.toString(), cartItem);
        } else {
            //如果 购物车 不为null
            //看看 购物车中 是否有该 商品
            CartItem current = cart.getItems().get(itemId.toString());

            if (current == null) {
                //购物车没有改商品
//                current = cartItem; 一定注意 这是错误的写法
                cart.getItems().put(itemId.toString(), cartItem);
            } else {
                //购物车有该商品 ，累加
                current.setNum(current.getNum() + num);
            }
        }
        //将新建的cart放入Redis缓存
        redisDao.set(cartKeyPrefix + user.getId(), cart);

        return HaustResult.ok();

        //自己的逻辑写法
//        //获得该商品的缓存key
//        String itemKey = itemKeyPrefix + itemId;
//
//        //获取 缓存中 该商品信息
//        TbItem item = redisDao.get(itemKey);
//
//        //通过用户id,获取购物车
//        //1、获取购物车缓存key
//        String cartKey=cartKeyPrefix + user.getId();
//        //2、通过购物车
//        Cart cart=redisDao.get(cartKey);
//
//        if (cart==null){
//            //如果 购物车为null
//            cart=new Cart();
//            CartItem cartItem = new CartItem();
//            BeanUtils.copyProperties(item,cartItem);
//            cartItem.setNum(num);
//
//            LinkedHashMap<String, CartItem> map = new LinkedHashMap<>();
//            map.put(itemId.toString(),cartItem);
//            cart.setItems(map);
//
//            redisDao.set(cartKey,cart);
//        }else {
//            //如果 购物车不为null
//            Map<String, CartItem> items =
//                    cart.getItems();
//
//            CartItem cartItem = items.get(itemId);
//            if (cartItem==null){
//                //购物车中没有同类的商品--添加
//                CartItem curCartItem = new CartItem();
//                BeanUtils.copyProperties(item,curCartItem);
//                curCartItem.setNum(num);
//                items.put(itemId.toString(),curCartItem);
//            }else{
//                //购物车中有该商品---累加
//                cartItem.setNum(cartItem.getNum()+num);
//            }
//            cart.setItems(items);
//
//        }
//
//        return HaustResult.ok();
    }
}
